package Java7_Concurrency_Cookbook.thread_executor_framework.completion_service;

import java.util.concurrent.*;

/**
 * 如果需要在一个对象里发送任务给执行器, 然后在另一个对象里处理结果.<br/>
 * 对于这种情况, Java并发API提供了CompletionService类<br/>
 *
 * Java并发API提供了CompletionService类提供了两种方法来获取已经完成任务的 Future 对象<br/>
 * pool(): 检查队列中是否有Future对象, 如果队列为空立即返回null.
 * 否则返回队列中的第一个元素, 并移除这个元素<br/>
 * take(): 检查队列中是否有Future对象, 如果队列为空, 它将阻塞线程直到队列中有可用元素.
 * 如果队列中有元素, 它将返回队列中的第一个元素, 并移除这个元素
 * @author lixiangke
 * @date 2017/11/20
 */
public class Main {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newCachedThreadPool();
        CompletionService<String> service = new ExecutorCompletionService<String>(executor);

        ReportRequest faceRequest = new ReportRequest("Face", service);
        ReportRequest onlineRequest = new ReportRequest("Online", service);
        Thread faceThread = new Thread(faceRequest);
        Thread onlineThread = new Thread(onlineRequest);

        ReportProcessor processor = new ReportProcessor(service);
        Thread senderThread = new Thread(processor);

        System.out.printf("Main: Starting the Threads\n");
        faceThread.start();
        onlineThread.start();
        senderThread.start();

        System.out.printf("Main: Waiting for the report generators.\n");
        faceThread.join();
        onlineThread.join();

        System.out.printf("Main: Shutting down the executor.\n");
        executor.shutdown();
        executor.awaitTermination(1, TimeUnit.DAYS);

        processor.setEnd(true);
        System.out.printf("Main: Ends");
    }
}
